<template>
  <div
      v-if="menus.length > 0"
      class="desktop-contextmenu-wrapper"
      :style="{display: visible ? 'block' : 'none'}"
      tabindex="0"
      @blur="hide()"
  >
    <ul>
      <li v-for="menu in menus"
          v-if="typeof menu !== 'string'"
          @click.stop="onMenuItemClick(menu)"
          @mouseover="onMenuItemMouseover(menu, $event)"
          class="cmenu-item"
      >
                <span v-if="hasIcon" class="cmenu-icon">
                    <i :class="['diconfont', menu.icon || '']"></i>
                </span>
        <span class="cmenu-name">{{menu.name}}</span>
        <span v-if="menu.subs && menu.subs.length > 0" class="cmenu-arrow-right">
                    <i :class="['diconfont', icon-arrow-right]"></i>
                </span>
      </li>
      <li v-else class="seperator" @click.stop="' '">
        <hr>
      </li>
    </ul>

    <div v-if="submenus && submenus.length > 0" class="desktop-contextmenu-wrapper submenu-wrapper">
      <ul>
        <li v-for="menu in submenus"
            v-if="typeof menu !== 'string'"
            @click.stop="onMenuItemClick(menu)"
            class="cmenu-item"
        >
            <span v-if="subMenuHasIcon" class="cmenu-icon">
                <i :class="['diconfont', menu.icon || '']"></i>
            </span>
            <span class="cmenu-name">{{menu.name}}</span>
        </li>
        <li v-else class="seperator" @click.stop="' '">
          <hr>
        </li>
      </ul>
    </div>
  </div>
</template>

<script>
  export default {
    name: "context-menu",

    props: {},

    data() {
      return {
        visible: false,

        menus: [
          {name: '刷新', icon: 'icon-shuaxin', fn: () => location.reload(true)},
          {name: '返回博客主页', icon: 'static/favicon.ico', fn: () => this.$router.push('/')},
          'seperator',
          {name: '刷新', icon: 'icon-shuaxin', fn: () => location.reload(true)},
          {name: '返回博客主页', icon: 'static/favicon.ico', fn: () => this.$router.push('/')},
          {name: '刷新', icon: 'icon-shuaxin', fn: () => location.reload(true)},
          {name: '返回博客主页', icon: 'static/favicon.ico', fn: () => this.$router.push('/')},
          'seperator',
          {name: '刷新', icon: 'icon-shuaxin', fn: () => location.reload(true)},
          {
            name: '更多', subs: [
              {name: '更多 one', icon: 'icon-loading',},
              {name: '更多 two', icon: 'icon-loading',},
              'seperator',
              {name: '更多 three', icon: 'icon-loading',},
              {name: '更多 four', icon: 'icon-loading', fn: () => alert('傻逼了吧')},
            ]
          },
        ],

        submenus: [],
      }
    },

    computed: {
      /** 菜单列表中是否有图标 */
      hasIcon() {
        return this.menus.findIndex(menu => menu && !!menu.icon) !== -1;
      },
      subMenuHasIcon() {
        return this.submenus.findIndex(menu => menu && !!menu.icon) !== -1;
      },
    },

    methods: {
      /**
       * 显示右键菜单
       * @public
       * @param {Array<{name:string,icon:string,fn:Function,subs:Array}>} menus 菜单列表
       *     格式: [{name: string, icon: string, fn: Function, subs: [{name,icon,fn} ...]} ...]
       * @param {MouseEvent} event 鼠标事件
       */
      show(menus, event) {
        this.visible = true;

        this.$nextTick(() => {
          this.$el.style.left = event.clientX + 'px';
          this.$el.style.top = event.clientY + 'px';
          this.$el.focus();
          // this.$el.style.zIndex = DesktopUtils.getNextZindex();

          this.calcMenuPosition();
        });
      },

      /** 隐藏菜单 */
      hide() {
        this.visible = false;
        this.submenus = [];
      },

      /** 菜单点击回调 */
      onMenuItemClick(menu) {
        if (typeof menu.fn === 'function') {
          menu.fn();
        }
        this.hide();
      },

      onMenuItemMouseover(menu, event) {
        if (menu.subs && menu.subs.length > 0) {
          const rect = event.currentTarget.getClientRects().item(0);

          this.submenus = menu.subs;

          this.$nextTick(() => {
            // 计算二级菜单的位置
            const $submenuWrapper = this.$el.querySelector('.submenu-wrapper');

            let left = rect.left + rect.width,
              top = rect.top;

            const wrapperRect = $submenuWrapper.getClientRects().item(0);

            if (left + wrapperRect.width > window.innerWidth) {
              left = rect.left - wrapperRect.width;
            }
            if (top + wrapperRect.height > window.innerHeight) {
              top = window.innerHeight - wrapperRect.height;
            }

            $submenuWrapper.style.left = left + 'px';
            $submenuWrapper.style.top = top + 'px';
          })

        } else {
          if (this.submenus && this.submenus.length > 0) {
            this.submenus = [];
          }
        }
      },

      /** 显示菜单时计算菜单的位置,防止出现在屏幕可视区域之外 */
      calcMenuPosition() {
        const rect = this.$el.getClientRects().item(0);
        if (rect.left + rect.width > window.innerWidth) {
          this.$el.style.left = window.innerWidth - rect.width + 'px';
        }
        if (rect.top + rect.height > window.innerHeight) {
          this.$el.style.top = window.innerHeight - rect.height + 'px';
        }
      },
    },

    mounted() {
    },

    updated() {
    },

    destroyed() {
    },
  }
</script>

<style lang="scss">
  .desktop-contextmenu-wrapper {
    position: fixed;
    top: 350px;
    left: 300px;

    min-width: 160px;
    background: rgba(#fff, .95);
    padding: 8px 0;
    z-index: 10;
    -webkit-box-shadow: rgba(0, 0, 0, .15) 0 0 0 0,
    rgba(0, 0, 0, .25) 0 2px 5px 0;
    border-radius: 2px;
    user-select: none;
    outline: none;

    ul {
      padding: 0;

      li {
        position: relative;
        height: 32px;
        line-height: 32px;
        text-align: left;
        font-size: 14px;
        cursor: pointer;
        -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
        padding: 0 22px 0 12px;
        transition: all .2s;
        box-sizing: border-box;
        overflow: hidden;

        display: flex;
        align-items: center;
        justify-content: flex-start;

        &.cmenu-item {

          &:hover {
            background: rgba(61, 64, 109, .15);
          }
        }

        &.seperator {
          height: 1px;
          padding: 5px 0;
          margin-left: 16px;
          cursor: default;

          hr {
            width: 100%;
            border: 0;
            border-top: 1px solid rgba(0, 0, 0, .05);
            outline: none;
          }
        }

        .cmenu-icon {
          display: inline-flex;
          align-items: center;
          justify-content: center;
          width: 22px;
          height: 100%;
          margin-right: 10px;

          i {
            font-size: 20px;
          }

          img {
            width: 18px;
            height: 18px;
          }
        }

        .cmenu-name {
          white-space: nowrap;
          text-overflow: ellipsis;
          overflow: hidden;
        }

        .cmenu-arrow-right {
          display: inline-flex;
          height: 100%;
          width: 20px;
          align-items: center;
          justify-content: flex-start;
          position: absolute;
          right: 0;
          color: #777;
          font-weight: lighter;
        }
      }
    }
  }
</style>
